/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hos_ahmedadeltito.photoeditorsdk;

import ohos.agp.components.*;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayAttributes;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.app.Environment;
import ohos.data.usage.DataUsage;
import ohos.data.usage.MountState;
import ohos.media.image.PixelMap;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.logging.Logger;

public class PhotoEditorSDK implements MultiTouchListener.OnMultiTouchListener {

    private Context context;
    private DependentLayout parentView;
    private Image imageView;
    private Component deleteView;
    private BrushDrawingView brushDrawingView;
    private List<Component> addedViews;
    private OnPhotoEditorSDKListener onPhotoEditorSDKListener;
    private Component addTextRootView;

    private PhotoEditorSDK(PhotoEditorSDKBuilder photoEditorSDKBuilder) {
        this.context = photoEditorSDKBuilder.context;
        this.parentView = photoEditorSDKBuilder.parentView;
        this.imageView = photoEditorSDKBuilder.imageView;
        this.deleteView = photoEditorSDKBuilder.deleteView;
        this.brushDrawingView = photoEditorSDKBuilder.brushDrawingView;
        addedViews = new ArrayList<>();
    }

    public void addImage(PixelMap desiredImage) {
        LayoutScatter inflater = LayoutScatter.getInstance(context);
        Component imageRootView = inflater.getInstance(context).parse(ResourceTable.Layout_photo_editor_sdk_image_item_list, null, false);

        Image imageView = (Image) imageRootView.findComponentById(ResourceTable.Id_photo_editor_sdk_image_iv);
        imageView.setPixelMap(desiredImage);
        imageView.setLayoutConfig(new DependentLayout.LayoutConfig(DependentLayout.LayoutConfig.MATCH_CONTENT,
            DependentLayout.LayoutConfig.MATCH_CONTENT));
        MultiTouchListener multiTouchListener = new MultiTouchListener(deleteView,
            parentView, this.imageView, onPhotoEditorSDKListener);
        multiTouchListener.setOnMultiTouchListener(this);
        imageRootView.setTouchEventListener(multiTouchListener);
        DependentLayout.LayoutConfig params = new DependentLayout.LayoutConfig(
            ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
        params.addRule(DependentLayout.LayoutConfig.CENTER_IN_PARENT, DependentLayout.LayoutConfig.TRUE);
        parentView.addComponent(imageRootView, params);
        addedViews.add(imageRootView);
        if (onPhotoEditorSDKListener != null)
            onPhotoEditorSDKListener.onAddViewListener(ViewType.IMAGE, addedViews.size());
    }

    public void addText(String text, Color colorCodeTextView) {

        LayoutScatter inflater = LayoutScatter.getInstance(context);
        addTextRootView = inflater.parse(ResourceTable.Layout_photo_editor_sdk_text_item_list, null, false);
        Text addTextView = (Text) addTextRootView.findComponentById(ResourceTable.Id_photo_editor_sdk_text_tv);
        addTextView.setTextAlignment(TextAlignment.CENTER);
        addTextView.setText(text);
        if (colorCodeTextView.getValue() != -1)
            addTextView.setTextColor(colorCodeTextView);
        MultiTouchListener multiTouchListener = new MultiTouchListener(deleteView,
            parentView, this.imageView, onPhotoEditorSDKListener);
        multiTouchListener.setOnMultiTouchListener(this);
        addTextRootView.setTouchEventListener(multiTouchListener);
        DependentLayout.LayoutConfig params = new DependentLayout.LayoutConfig(
            ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
        params.addRule(DependentLayout.LayoutConfig.CENTER_IN_PARENT, DependentLayout.LayoutConfig.TRUE);
        parentView.addComponent(addTextView, params);
        addedViews.add(addTextRootView);
        if (onPhotoEditorSDKListener != null)
            onPhotoEditorSDKListener.onAddViewListener(ViewType.TEXT, addedViews.size());
    }

    public void addEmoji(String emojiName, Font emojiFont) {
        LayoutScatter inflater = LayoutScatter.getInstance(context);
        DependentLayout emojiRootView = (DependentLayout) inflater.parse(ResourceTable.Layout_photo_editor_sdk_emoji_item_list, null, false);

        Text text = new Text(context);
        text.setTextSize(35, Text.TextSizeType.FP);
        text.setTextAlignment(TextAlignment.CENTER);
        text.setText(emojiName);
        text.setFont(emojiFont);
        Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(context);
        DisplayAttributes displayAttributes = display.get().getAttributes();
        int mItemWidth = displayAttributes.width / 4;
        DirectionalLayout.LayoutConfig itemLayoutConfig = new DirectionalLayout.LayoutConfig(mItemWidth, mItemWidth);
        emojiRootView.addComponent(text, itemLayoutConfig);
        MultiTouchListener multiTouchListener = new MultiTouchListener(deleteView,
            parentView, this.imageView, onPhotoEditorSDKListener);
        multiTouchListener.setOnMultiTouchListener(this);
        emojiRootView.setTouchEventListener(multiTouchListener);
        DependentLayout.LayoutConfig params = new DependentLayout.LayoutConfig(
            ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
        params.addRule(DependentLayout.LayoutConfig.CENTER_IN_PARENT, DependentLayout.LayoutConfig.TRUE);
        parentView.addComponent(emojiRootView, params);
        addedViews.add(emojiRootView);
        if (onPhotoEditorSDKListener != null)
            onPhotoEditorSDKListener.onAddViewListener(ViewType.EMOJI, addedViews.size());
    }


    public void setBrushDrawingMode(boolean brushDrawingMode) {
        if (brushDrawingView != null)
            brushDrawingView.setBrushDrawingMode(brushDrawingMode);
    }

    public void setBrushSize(float size) {
        if (brushDrawingView != null)
            brushDrawingView.setBrushSize(size);
    }

    public void setBrushColor(Color color) {
        if (brushDrawingView != null)
            brushDrawingView.setBrushColor(color);
    }

    public void setBrushEraserSize(float brushEraserSize) {
        if (brushDrawingView != null)
            brushDrawingView.setBrushEraserSize(brushEraserSize);
    }

    public void setBrushEraserColor(Color color) {
        if (brushDrawingView != null)
            brushDrawingView.setBrushEraserColor(color);
    }

    public float getEraserSize() {
        if (brushDrawingView != null)
            return brushDrawingView.getEraserSize();
        return 0;
    }

    public float getBrushSize() {
        if (brushDrawingView != null)
            return brushDrawingView.getBrushSize();
        return 0;
    }

    public Color getBrushColor() {
        if (brushDrawingView != null)
            return brushDrawingView.getBrushColor();
        return new Color(0);
    }

    public void brushEraser() {
        if (brushDrawingView != null)
            brushDrawingView.brushEraser();
    }

    public void viewUndo() {
        if (addedViews.size() > 0) {
            parentView.removeComponent(addedViews.remove(addedViews.size() - 1));
            if (onPhotoEditorSDKListener != null)
                onPhotoEditorSDKListener.onRemoveViewListener(addedViews.size());
        }
    }

    private void viewUndo(Component removedView) {
        if (addedViews.size() > 0) {
            if (addedViews.contains(removedView)) {
                parentView.removeComponent(removedView);
                addedViews.remove(removedView);
                if (onPhotoEditorSDKListener != null)
                    onPhotoEditorSDKListener.onRemoveViewListener(addedViews.size());
            }
        }
    }

    public void clearBrushAllViews() {
        if (brushDrawingView != null)
            brushDrawingView.clearAll();
    }

    public void clearAllViews() {
        for (int i = 0; i < addedViews.size(); i++) {
            parentView.removeComponent(addedViews.get(i));
        }
        if (brushDrawingView != null)
            brushDrawingView.clearAll();
    }

    public String saveImage(String folderName, String imageName) {

        String selectedOutputPath = "";
        if (isSDCARDMounted()) {
            File mediaStorageDir = new File(
                context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), folderName
            );
            // 如果存储目录不存在,请创建它
            if (!mediaStorageDir.exists()) {
                if (!mediaStorageDir.mkdirs()) {
                    LogUtils.showLog("Failed to create directory");
                }
            }
            // 创建一个媒体文件名
            selectedOutputPath = mediaStorageDir.getPath() + File.separator + imageName;
            LogUtils.showLog("selected camera path " + selectedOutputPath);
            File file = new File(selectedOutputPath);
            try {
                FileOutputStream out = new FileOutputStream(file);
                if (parentView != null) {
                    //todo 未找到解决方案 启用绘图缓存
//                    parentView.setDrawingCacheEnabled(true);
                    //todo 将位图的压缩版本写入指定的outputstream。如果返回true，则可以通过将o对应的inputstream传递给BitmapFactorv, decodestream()来重构位图
//                    parentView.getDrawingCache().compress(PixelMap.CompressFormat.JPEG, 80, out);
                }
                out.flush();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return selectedOutputPath;
    }

    private boolean isSDCARDMounted() {
        //todo 未找到解决方案 返回主共享/外部存储介质的当前状态。
//        String status = Environment.getExternalStorageState();
        MountState status = DataUsage.getDiskMountedStatus();//查询主设备的挂载状态
        return status.equals(MountState.DISK_MOUNTED);//MEDIA_MOUNTED 表示设备已经挂载
    }

    private String convertEmoji(String emoji) {
        String returnedEmoji = "";
        try {
            int convertEmojiToInt = Integer.parseInt(emoji.substring(2), 16);
            returnedEmoji = getEmojiByUnicode(convertEmojiToInt);
        } catch (NumberFormatException e) {
            returnedEmoji = "";
        }
        return returnedEmoji;
    }

    private String getEmojiByUnicode(int unicode) {
        return new String(Character.toChars(unicode));
    }

    public void setOnPhotoEditorSDKListener(OnPhotoEditorSDKListener onPhotoEditorSDKListener) {
        this.onPhotoEditorSDKListener = onPhotoEditorSDKListener;
        brushDrawingView.setOnPhotoEditorSDKListener(onPhotoEditorSDKListener);
    }

    @Override
    public void onEditTextClickListener(String text, int colorCode) {
        if (addTextRootView != null) {
            addTextRootView.setVisibility(Component.INVISIBLE);
//            parentView.removeComponent(addTextRootView);
            addedViews.remove(addTextRootView);
        }
    }

    @Override
    public void onRemoveViewListener(Component removedView) {
        viewUndo(removedView);
    }


    public static class PhotoEditorSDKBuilder {
        private Context context;
        private DependentLayout parentView;
        private Image imageView;
        private Component deleteView;
        private BrushDrawingView brushDrawingView;

        public PhotoEditorSDKBuilder(Context context) {
            this.context = context;
        }

        public PhotoEditorSDKBuilder parentView(DependentLayout parentView) {
            this.parentView = parentView;
            return this;
        }

        public PhotoEditorSDKBuilder childView(Image imageView) {
            this.imageView = imageView;
            return this;
        }

        public PhotoEditorSDKBuilder deleteView(Component deleteView) {
            this.deleteView = deleteView;
            return this;
        }

        public PhotoEditorSDKBuilder brushDrawingView(BrushDrawingView brushDrawingView, PixelMap pixelMap) {
            this.brushDrawingView = brushDrawingView;
            brushDrawingView.setImage(pixelMap);
            return this;
        }

        public PhotoEditorSDK buildPhotoEditorSDK() {
            return new PhotoEditorSDK(this);
        }
    }
}
